<html>
<head><meta charset="utf-8"><title>Out keyword to suppress E0381 · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html">Out keyword to suppress E0381</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="243729660"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243729660" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Guillaume Xavier Taillon <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243729660">(Jun 24 2021 at 00:22)</a>:</h4>
<p>Hello, I can't seem to find documentation on out-only parameters in rust.</p>
<p>I'm trying to supress/fix rustcE0381 on a function that <em>must</em> initialize the buffer:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">num_buffer</span>: <span class="p">[</span><span class="kt">u8</span><span class="p">;</span><span class="w"> </span><span class="mi">8</span><span class="p">];</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">bytes</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="kt">u8</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">init_from</span><span class="p">(</span><span class="n">v</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">num_buffer</span><span class="p">);</span><span class="w"></span>
<span class="n">finish</span><span class="p">(</span><span class="n">bytes</span><span class="p">)</span><span class="w"></span>
</code></pre></div>
<p>I'm trying to reuse code that copies &amp; transforms bytes obtained from a <code>to_le_bytes()</code> and/or <code>as_bytes()</code> from deep inside a struct v.</p>
<p>In C# I could tell the compiler that it doesnt matter num_buffer isnt initialized by declaring the param with out, which also constraints the function to intialize the param. Is there something similar in (std) rust?</p>
<p>Best,<br>
gxt</p>
<p><a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/out-parameter-modifier">https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/out-parameter-modifier</a></p>



<a name="243729847"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243729847" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243729847">(Jun 24 2021 at 00:26)</a>:</h4>
<p>Short answer: no. The only true "out parameters" in rust are return values</p>



<a name="243729975"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243729975" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243729975">(Jun 24 2021 at 00:29)</a>:</h4>
<p>If you really need to do this, you can use <code>&amp;mut MaybeUninit&lt;[u8; 8]&gt;</code> and a healthy sprinkling of <code>unsafe</code></p>



<a name="243730506"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243730506" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Guillaume Xavier Taillon <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243730506">(Jun 24 2021 at 00:41)</a>:</h4>
<p>Thanks! That's a lot more unsafe than I expected haha, I'll check it out.</p>



<a name="243735623"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243735623" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243735623">(Jun 24 2021 at 02:32)</a>:</h4>
<p>Barring MaybeUninit, a type is a valid instance of its type only if it is initialized. You can just use something like</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">bytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">init_from</span><span class="p">(</span><span class="n">v</span><span class="p">);</span><span class="w"></span>
<span class="n">finish</span><span class="p">(</span><span class="n">bytes</span><span class="p">)</span><span class="w"></span>
</code></pre></div>
<p>where init_from returns <code>[u8; 8]</code> instead.</p>



<a name="243751253"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243751253" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243751253">(Jun 24 2021 at 07:41)</a>:</h4>
<p><span class="user-mention silent" data-user-id="421637">Guillaume Xavier Taillon</span> <a href="#narrow/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381/near/243729660">said</a>:</p>
<blockquote>
<p>In C# I could tell the compiler that it doesnt matter num_buffer isnt initialized by declaring the param with out, which also constraints the function to intialize the param. Is there something similar in (std) rust?</p>
</blockquote>
<p>Note that C# is <a href="https://docs.microsoft.com/en-us/dotnet/api/system.reflection.parameterinfo.isout?view=net-5.0#remarks">slightly</a> lying to you there, as at the CLR level it's just a <code>ref</code> parameter that the compiler initialized to <code>default</code> before calling the method.  You can swap out the implementing DLL to one that doesn't initialize the value and the bytecode verifier will accept it.</p>
<p>So the direct equivalent is passing a <code>&amp;mut</code> either to <code>let mut num_buffer: Option&lt;[u8; 8]&gt; = None;</code> (if you're thinking a reference type in C#) or to zero-initialize the buffer before calling it (if you're thinking a value type in C#).</p>
<p>(C# can zero-initialize everything, but Rust can't, which is why the difference here exists.)</p>



<a name="243760853"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243760853" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243760853">(Jun 24 2021 at 09:32)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381/near/243729975">said</a>:</p>
<blockquote>
<p>If you really need to do this, you can use <code>&amp;mut MaybeUninit&lt;[u8; 8]&gt;</code> and a healthy sprinkling of <code>unsafe</code></p>
</blockquote>
<p>With the major caveat that <code>&amp;mut T</code> =&gt; <code>&amp;mut MaybeUninit&lt;T&gt;</code> is not, in general, sound (althouhg it can be done interanly in sound APIs in specific cases) as the T can be overwritten with <code>MaybeUninit::uninit()</code></p>



<a name="243784797"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243784797" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243784797">(Jun 24 2021 at 13:25)</a>:</h4>
<p><span class="user-mention" data-user-id="209168">@Thom Chiovoloni</span>, you shouldn't need to perform that cast here, right? You "uninitialize" the buffer by replacing <code>let num_buffer: [u8; 8];</code> with <code>let num_buffer = MaybeUninit::&lt;[u8; 8]&gt;::uninit();</code> and then pass a mutable reference to that to <code>init_from</code> and <code>assume_init()</code> it before passing to <code>finish()</code></p>



<a name="243785103"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243785103" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243785103">(Jun 24 2021 at 13:27)</a>:</h4>
<p>But to reiterate what others (and I) have said, using return values is <em>the</em> way to do this. They are perfect out parameters, especially if RVO works properly, and you don't need any unsafe.</p>



<a name="243836879"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243836879" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243836879">(Jun 24 2021 at 19:45)</a>:</h4>
<p>Yeah, you can do it without that cast, although it would be easy to think that cast was fine, and design an api that assumed it, so I figured I'd mention it.</p>
<p>Also I've sadly seen tons of cases where out-params are needed for perf for various reasons... Hopefully LLVM is a bit better now, since it's been a couple years, but it used to get very confused...</p>



<a name="243849626"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243849626" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243849626">(Jun 24 2021 at 21:33)</a>:</h4>
<p>observationally as far as I can tell code returning arrays becomes something pretty decent at opt-level=3, but if it's more dynamic, it might have more problems.</p>



<a name="243850275"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243850275" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243850275">(Jun 24 2021 at 21:40)</a>:</h4>
<p>makes me think we need better ABIs that support using more registers for return values and not just the one or two that the C ABIs use...</p>



<a name="243850364"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243850364" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243850364">(Jun 24 2021 at 21:41)</a>:</h4>
<p>ideally you can use as many registers for return values as you can use for argument values</p>



<a name="243854408"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/243854408" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#243854408">(Jun 24 2021 at 22:27)</a>:</h4>
<p>the cases i'm thinking of weren't arrays, but yeah, the ABI was a problem. Part of why I'm glad we keep it flexible, even if it is sometimes inconvenient</p>



<a name="244012702"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Out%20keyword%20to%20suppress%20E0381/near/244012702" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Out.20keyword.20to.20suppress.20E0381.html#244012702">(Jun 26 2021 at 12:26)</a>:</h4>
<p><a href="https://docs.rs/uninit">https://docs.rs/uninit</a> explains these issues quite in detail and offers an <code>Out&lt;'_, T&gt;</code> parameter pointer type</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>